/*
 * DefaultButtonModel.java  0.4.0 / Oct 26, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing;

import com.cute4j.core.events.EventListenerList;
import com.cute4j.swing.events.ChangeEvent;
import com.cute4j.swing.events.ChangeListener;

/**
 * Default Button Model.
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public class DefaultButtonModel implements ButtonModel {

// Private Fields. -------------------------------------------------------------

  private boolean enabled;
  private boolean pressed;
  private boolean selected;

// Protected Fields. -----------------------------------------------------------

  protected ChangeEvent changeEvent;
  protected final EventListenerList listenerList;

// Public Constructors. --------------------------------------------------------

  /**
   * Constructs new DefaultButtonModel object.
   */
  public DefaultButtonModel() {
    enabled = true;
    listenerList = new EventListenerList();
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Returns change listeners.
   *
   * @return change listeners
   */
  public ChangeListener[] getChangeListeners() {
    int count = listenerList.getListenerCount(ChangeListener.class);
    ChangeListener[] listeners = new ChangeListener[count];
    if (count > 0) {
      System.arraycopy(listenerList.getListenersArray(ChangeListener.class), 0,
                       listeners,  0, count);
    }
    return listeners;
  }

// Protected Methods. ----------------------------------------------------------

  /**
   * Fires state changed event.
   */
  protected void fireStateChanged() {
    int count = listenerList.getListenerCount(ChangeListener.class);
    if (count > 0) {
      ChangeListener[] listeners = (ChangeListener[])listenerList.
                                       getListenersArray(ChangeListener.class);
      ChangeEvent changeEvent = this.changeEvent;
      if (changeEvent == null) {
        changeEvent = new ChangeEvent(this);
        this.changeEvent = changeEvent;
      }
      for (int i = count; --i >= 0;) {
        listeners[i].stateChanged(changeEvent);
      }
    }
  }

// ButtonModel Interface Implementation. ---------------------------------------

  /**
   * {@inheritDoc}
   */
  public boolean isEnabled() {
    return enabled;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isPressed() {
    return pressed;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isSelected() {
    return selected;
  }

  /**
   * {@inheritDoc}
   */
  public void setEnabled(boolean enabled) {
    if (this.enabled != enabled) {
      this.enabled = enabled;
      fireStateChanged();
    }
  }

  /**
   * {@inheritDoc}
   */
  public void setPressed(boolean pressed) {
    if (enabled && (this.pressed != pressed)) {
      this.pressed = pressed;
      fireStateChanged();
    }
  }

  /**
   * {@inheritDoc}
   */
  public void setSelected(boolean selected) {
    if (enabled && (this.selected != selected)) {
      this.selected = selected;
      fireStateChanged();
    }
  }

  /**
   * {@inheritDoc}
   */
  public void addChangeListener(ChangeListener listener) {
    listenerList.add(ChangeListener.class, listener);
  }

  /**
   * {@inheritDoc}
   */
  public void removeChangeListener(ChangeListener listener) {
    listenerList.remove(ChangeListener.class, listener);
  }

// Inner Classes. --------------------------------------------------------------

  /**
   * Empty Model.
   */
  public static class EmptyModel implements ButtonModel {
    public static final EmptyModel INSTANCE = new EmptyModel();
    public boolean isEnabled() {
      return false;
    }
    public boolean isPressed() {
      return false;
    }
    public boolean isSelected() {
      return false;
    }
    public void setEnabled(boolean enabled) {
      // empty method
    }
    public void setPressed(boolean pressed) {
      // empty method
    }
    public void setSelected(boolean selected) {
      // empty method
    }
    public void addChangeListener(ChangeListener listener) {
      // empty method
    }
    public void removeChangeListener(ChangeListener listener) {
      // empty method
    }
  }
}
